Suavização de Séries Temporais

Aplicação de médias móveis, suavização exponencial, método de Holt e Holt-Winters

# Bibliotecas para uso geral
library(tidyverse)
library(plotly)
library(glue)

Médias Móveis Simples

Utilizaremos a função ma do pacote forecast para suavização e o dataset de concentrações atmosféricas de CO2.

library(forecast)
library(zoo)
data(co2)
co2_df = tibble(
  date = as.Date(as.yearmon(time(co2))),
  value = as.numeric(co2)
)
co2_df |> 
  ggplot(aes(x = date, y = value)) +
  geom_line() +
  labs(
    title = "Concentração atmosférica mensal de CO2",
    x = "Mês",
    y = "Concentração"
   ) +
  theme_minimal()

# Computar MMS com ordem 3, 5 e 7
ma.co2.3 = ma(co2, order = 3)
ma.co2.5 = ma(co2, order = 5)
ma.co2.7 = ma(co2, order = 7)
ggplotly(
tibble(
  date = as.Date(as.yearmon(time(co2))),
  original = as.numeric(co2),
  ma.3 = as.numeric(ma.co2.3),
  ma.5 = as.numeric(ma.co2.5),
  ma.7 = as.numeric(ma.co2.7)
) |> 
  ggplot(aes(x = date)) +
  geom_line(aes(y = original, color = "Orginal"))+
  geom_line(aes(y = ma.3, color = "k = 3")) +
  geom_line(aes(y = ma.5, color = "k = 5")) +
  geom_line(aes(y = ma.7, color = "k = 7"))+
  labs(
    title = "Suavização por MMS",
    x = "Data",
    y = "Concentração"
  )
)  

Suavização Exponencial Simples (SES)

Utilizaremos a função ets da biblioteca forecast. Testaremos com 3 valores para alpha. A mesma função será utilizada posteriormente para os métodos de Holt e Holt-Winters.

model.0.1 = ets(
  co2, 
  model = "ANN", # Denota o SES
  alpha = 0.1
)
model.0.5 = ets(
  co2, 
  model = "ANN", 
  alpha = 0.5
)
model.0.9 = ets(
  co2, 
  model = "ANN", # Denota o SES
  alpha = 0.9
)
ggplotly(
tibble(
    date = as.Date(as.yearmon(time(co2))),
    original = as.numeric(co2),
    es.0.1 = as.numeric(model.0.1$fitted),
    es.0.5 = as.numeric(model.0.5$fitted),
    es.0.9 = as.numeric(model.0.9$fitted),
  ) |> 
    ggplot(aes(x = date)) +
    geom_line(aes(y = original, color = "Original")) +
    geom_line(aes(y = es.0.1, color = "\u03b1 = 0.1")) +
    geom_line(aes(y = es.0.5, color = "\u03b1 = 0.5")) +
    geom_line(aes(y = es.0.9, color = "\u03b1 = 0.9")) +
    labs(
      x = "Data",
      y = "Concentração",
      title = "Suavização Exponencial Simples"
  )
)

Método de Holt

Para o método de Holt e Holt-Winters utilizaremos a série de desemprego nos EUA. Em vez de manualmente determinar parâmetros, utilizaremos a funcionalidade de seleção de modelo, já implementada na função. Serão ajustados modelos multiplicativos e aditivos.

data("economics")
#unemploy.ts = ts(economics$unemploy)
holt.add = ets(
  economics$unemploy,
  model = "AAN", # Holt aditivo
)
holt.mult = ets(
  economics$unemploy,
  model = "MMN" # Holt com tendencia multiplicativa 
)
print("Parâmetros Holt aditivo")
## [1] "Parâmetros Holt aditivo"
print(glue("\u03b1 = {holt.add$par['alpha']}"))
## α = 0.810920515164553
print(glue("\u03b2 = {holt.add$par['beta']}"))
## β = 0.243945559420687
print(glue("MSE = {holt.add$mse}"))
## MSE = 38907.2061430284
print("Parâmetros Holt multiplicativo")
## [1] "Parâmetros Holt multiplicativo"
print(glue("\u03b1 = {holt.mult$par['alpha']}"))
## α = 0.80292190813586
print(glue("\u03b2 = {holt.mult$par['beta']}"))
## β = 0.216966994712164
print(glue("MSE = {holt.mult$mse}"))
## MSE = 38744.2600476085
ggplotly(
  data.frame(
    x = 1:length(economics$unemploy),
    original = economics$unemploy,
    additive = holt.add$fitted, 
    multiplicative = holt.mult$fitted
  ) |> 
    ggplot(aes(x = x)) +
    geom_line(aes(y = original, color = "Original")) +
    geom_line(aes(y = additive, color = "Holt aditivo")) +
    geom_line(aes(y = multiplicative, color = "Holt multiplicativo")) +
    labs(
      title = "Desemprego (EUA) com método de Holt",
      x = "x (datas indeterminadas)",
      y = "Desempregados em milhares"
    )
)

Método de Holt-Winters

Utilizaremos novamente a série de concentrações de CO2, pois é necessária sazonalidade, caso contrário, a função ets retorna um erro.

hw.add = ets(
  co2,
  model = "AAA", # Holt-Winters aditivo
)
hw.mult = ets(
  co2,
  model = "MMM" # Holt-Winters multiplicativo 
)
print("Parâmetros Holt-Winters aditivo")
## [1] "Parâmetros Holt-Winters aditivo"
print(glue("\u03b1 = {hw.add$par['alpha']}"))
## α = 0.578450027739227
print(glue("\u03b2 = {hw.add$par['beta']}"))
## β = 0.00614301288873308
print(glue("\u03b3 = {hw.add$par['gamma']}"))
## γ = 0.137297074395071
print(glue("MSE = {hw.add$mse}"))
## MSE = 0.0834765548988027
print("Parâmetros Holt-Winters multiplicativo")
## [1] "Parâmetros Holt-Winters multiplicativo"
print(glue("\u03b1 = {hw.mult$par['alpha']}"))
## α = 0.532550302467779
print(glue("\u03b2 = {hw.mult$par['beta']}"))
## β = 0.0543390761294751
print(glue("\u03b3 = {hw.mult$par['gamma']}"))
## γ = 0.0722784925251422
print(glue("MSE = {hw.mult$mse}"))
## MSE = 0.0831224838356937
ggplotly(
  data.frame(
    x = as.Date(as.yearmon(time(co2))),
    original = as.numeric(co2),
    additive = hw.add$fitted, 
    multiplicative = hw.mult$fitted
  ) |> 
    ggplot(aes(x = x)) +
    geom_line(aes(y = original, color = "Original")) +
    geom_line(aes(y = additive, color = "Holt-Winters aditivo")) +
    geom_line(aes(y = multiplicative, color = "Holt-Winters multiplicativo")) +
    labs(
      title = "Concentração de CO2 com método de Holt-Winters",
      x = "data",
      y = "Concentração de CO2"
    )
)